﻿using AutoMapper;
using Microsoft.EntityFrameworkCore;
using QMERP.Domain.Dtos;
using QMERP.Domain.Entities;
using QMERP.Domain.Enums;
using QMERP.Infrastructure.CustomException;
using QMERP.Infrastructure.EFCore;
using QMERP.Infrastructure.EFCore.Extensions;
using QMERP.Infrastructure.Extensions;
using QMERP.Infrastructure.Security;
using QMERP.Infrastructure.Tools;

namespace QMERP.Application.Services
{
    public class UserService : IUserService
    {
        private readonly IMapper _mapper;
        private readonly ICurrentUser _currentUser;
        private readonly QMERPDbContext _db;
        public UserService(IMapper mapper, QMERPDbContext db,  ICurrentUser currentUser)
        {
            _mapper = mapper;
            _db = db;
            _currentUser = currentUser;
        }
        /// <summary>
        /// 获取当前登录用户详情(基本信息)
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task<CurrentUserResponse> CurrentUser()
        {
            var model = await _db.User.Include(x => x.User_Roles).ThenInclude(x => x.Role).Include(x => x.User_Organizations).ThenInclude(x => x.Organization).FindByIdAsync(_currentUser.Id);
            var organizations = await _db.Organization.ToListAsync();
            return _mapper.Map<CurrentUserResponse>(model);
        }
        /// <summary>
        /// 用户页面
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        public async Task<PageResponse<UserResponse>> Query(PageRequest<UserRequest> request)
        {
            var query = Where(request);
            var list = await query.Paging(request.PageIndex, request.PageSize).ToListAsync();
            var response = new PageResponse<UserResponse>
            {
                TotalCount = await query.CountAsync(),
                PageIndex = request.PageIndex,
                PageSize = request.PageSize,
                List = _mapper.Map<List<UserResponse>>(list)
            };
            return response;
        }
        /// <summary>
        /// 获取id的用户详情
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task<UserResponse> Detail(long id)
        {
            var model = await _db.User.Include(x => x.User_Roles).ThenInclude(x => x.Role).Include(x => x.User_Organizations).ThenInclude(x => x.Organization).FindByIdAsync(id);
            var response = _mapper.Map<UserResponse>(model);
            response.RoleNames = _db.Role.Where(x => response.RoleIds!.Contains(x.Id)).Select(s => s.Name).ToList();
            return response;
        }
        /// <summary>
        /// 用户保存
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        /// <exception cref="ApiException"></exception>
        public async Task Save(UserSaveRequest request)
        {
            if (_db.User.Any(x => x.Name.ToLower() == request.Name && x.Id != request.Id))
                throw new ApiException("用户名称已存在!");
            if (_db.User.Any(x => x.UserName.ToLower() == request.UserName && x.Id != request.Id))
                throw new ApiException("用户账号已存在!");

            User? model = _mapper.Map<User>(request);
            if (request.Id != null)
            {
                model = await _db.User.Include(x => x.User_Organizations).FindByIdAsync(request.Id.Value);
                if (model == null)
                    throw new ApiException("用户不存在!");
                model.Name = request.Name;
                model.UserName = request.UserName;
                model.Password = request.Password;
                model.Remark = request.Remark;
                _db.RemoveRange(model.User_Organizations);
            }
            else
            {
                //绑定默认用户角色
                User_Role user_Role = new()
                {
                    RoleId = ConfigurationUtils.GetSection("DefaultRoleId").ToInt(),
                };
                model.User_Roles.Add(user_Role);
            }
            if (request.OrganizationIds.Length > 0)
            {
                List<User_Organization> user_Organizations = new();
                foreach (var organizationId in request.OrganizationIds)
                {
                    User_Organization user_Organization = new()
                    {
                        OrganizationId = organizationId
                    };
                    user_Organizations.Add(user_Organization);
                }
                model.User_Organizations = user_Organizations;
            }
            if (request.Id == null)
                await _db.AddAsync(model);

            await _db.SaveChangesAsync();
        }
        /// <summary>
        /// 用户删除(假删除)
        /// </summary>
        /// <returns></returns>
        public async Task Remove(UserRemoveRequest request)
        {
            await _db.User.RemoveAsync(request.Ids.ToArray());
            await _db.SaveChangesAsync();
        }
        /// <summary>
        /// 登录
        /// </summary>
        /// <param name="userName"></param>
        /// <param name="password"></param>
        /// <returns></returns>
        /// <exception cref="ApiException"></exception>
        public async Task<LoginResponse> SignIn(string userName,string password)
        {
            var query = _db.User.Where(x => x.UserName == userName);
            if (!await query.AnyAsync())
            {
                throw new ApiException("用户名错误!");
            }
            var user = await query.FirstOrDefaultAsync(x => x.Password == password) ?? throw new ApiException("密码错误!");
            LoginResponse response = new()
            {
                Id = user.Id,
                UserName = user.UserName
            };
            return response;
        }
        /// <summary>
        /// 根据id获取用户的主要信息
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task<MainUserResponse> GetMainUserById(int id)
        {
            MainUserResponse response = new();
            var user = await _db.User.
                Include(x => x.User_Organizations).ThenInclude(x => x.Organization).ThenInclude(x => x!.Organization_Roles)
                .Include(x => x.User_Roles).FindByIdAsync(id);
            if (user != null)
            {
                response.Id = user.Id;
                response.UserName = user.UserName;
                response.Name = user.Name;
                response.IsEnable = user.IsEnable;
                if (user.User_Roles!.Count > 0)
                {
                    if (user.User_Roles.Any(x => x.RoleId == ConfigurationUtils.GetSection("AdminRoleId").ToInt()))
                    {
                        response.IsAdmin = true;
                    }
                    else
                    {
                        //获取用户的角色Ids
                        var userRoleIds = user.User_Roles.Select(s => s.RoleId).ToArray();
                        //获取用户的组织机构
                        var organizationIds = user.User_Organizations.Select(s => s.OrganizationId).ToArray();
                        //获取用户的组织机构的角色Ids
                        var organizationRoleIds = user.User_Organizations.SelectMany(s => s.Organization!.Organization_Roles).Select(s => s.RoleId).ToArray();
                        //获取资源列表
                        long[] appIds = await _db.Privilege.GetByMasterValues(user.Id, organizationIds, userRoleIds, organizationRoleIds).Where(x => x.Access == AccessEnum.App.ToString()).Select(s => s.AccessValue).Distinct().ToArrayAsync();
                        var licenses = await _db.App.Where(x => appIds.Contains(x.Id) && x.License != null && x.License != "").Select(s => s.License!).ToArrayAsync();
                        response.Licenses = licenses;
                    }
                }
            }
            return response;
        }

        private IQueryable<User> Where(PageRequest<UserRequest> request)
        {
            IQueryable<User> query = _db.User.Include(x => x.User_Roles).ThenInclude(x => x.Role).Include(x => x.User_Organizations).ThenInclude(x => x.Organization);

            if (request.Query.OrganizationId != null)
            {
                query = query.GetByOrganizationId(request.Query.OrganizationId.Value);
            }
            if (!request.Query.Name.IsNullOrWhiteSpace())
            {
                query = query.Where(x => x.Name.Contains(request.Query.Name!));
            }
            if (!request.Query.UserName.IsNullOrWhiteSpace())
            {
                query = query.Where(x => x.UserName.Contains(request.Query.UserName!));
            }
            return query.OrderByDescending(x => x.CreatedOn);
        }
    }
}
